package com.example.wearing.index;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.ViewModelProvider;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.location.Address;
import android.location.Geocoder;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.bigkoo.pickerview.OptionsPickerView;
import com.example.wearing.LoginActivity;
import com.example.wearing.MainActivity;
import com.example.wearing.R;
import com.example.wearing.javabean.Clothes;
import com.example.wearing.javabean.Match;
import com.example.wearing.javabean.ProvinceBean;
import com.example.wearing.javabean.User;
import com.example.wearing.tools.BitmapBinder;
import com.example.wearing.tools.ClothesListAdapter;
import com.example.wearing.tools.ClothesOfMatchAdapter;
import com.example.wearing.tools.ImageUtil;
import com.example.wearing.tools.JsonFileReader;
import com.example.wearing.tools.NetUtil;
import com.example.wearing.wardrobe.AddClothesActivity;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.QueryListener;

public class IndexFragment extends Fragment {

    /*
    任务：
    1、获取用户名，显示“欢迎回来，XXX”
    2、天气显示：
        默认选择地区，可点击更换地区
        网络爬取天气情况：图标、文字（天气、推荐语）、日期、最高最低温度
    3、根据天气推荐衣物：
        衣物数量<10or衣物类别<5————推荐文字
        足够衣物————推荐图片（搭配）

    */

    private IndexViewModel mViewModel;
    private GridView todayMatchList;
    private LinearLayout sitePart;
    private TextView welcomeUser, weatherText, lowTemp, highTemp, dateText, siteText, nodata, matchFeedback;
    private ImageView weatherImg;
    private ProgressBar bar;
    private int userId;
    private static final String TAG = "IndexFragment";
    private String jdbcUrl ,jdbcUser ,jdbcPassword;

    //处理城市选择
    private TextView mTextViewAddress;
    OptionsPickerView pvOptions;
    //  省份
    ArrayList<List<String>> provinceList = new ArrayList<>();
    ArrayList<ProvinceBean> provinceBeanList = new ArrayList<>();
    //  城市
    ArrayList<String> cities;
    ArrayList<List<String>> cityList = new ArrayList<>();
    //  区/县
    ArrayList<String> district;
    ArrayList<List<String>> districts;
    ArrayList<List<List<String>>> districtList = new ArrayList<>();

    String weatherCity; //城市
    double latitude; //纬度
    int month; //月份
    double Ta; //当前温度
    double RH; //相对湿度%
    double V; //风速，m/s
    boolean isRain = false;
    int level; //穿衣等级
    int baseLevel, feedbackNum; //用户可调整的穿衣等级
    ArrayList<String[]> clothesOfMatch = new ArrayList<>(); //推荐穿搭方案——服装名称
    ArrayList<ArrayList<String>> clothesImgOfMatch = new ArrayList<>(); //穿搭方案——图片
    ClothesOfMatchAdapter clothesOfMatchAdapter;


    public static IndexFragment newInstance() {
        return new IndexFragment();
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.index_fragment, container, false);
        todayMatchList = view.findViewById(R.id.todayMatchList);
        welcomeUser = view.findViewById(R.id.welcomeUser);
        weatherText = view.findViewById(R.id.weatherText);
        lowTemp = view.findViewById(R.id.lowTemp);
        highTemp = view.findViewById(R.id.highTemp);
        dateText = view.findViewById(R.id.dateText);
        siteText = view.findViewById(R.id.siteText);
        sitePart = view.findViewById(R.id.sitePart);
        weatherImg = view.findViewById(R.id.weatherImg);
        nodata = view.findViewById(R.id.nodataText);
        bar = view.findViewById(R.id.progressBar);
        matchFeedback = view.findViewById(R.id.matchFeedback);
        return view;
    }

    //接收天气情况
    private Handler mHandler = new Handler(Looper.myLooper()){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            if(msg.what == 0){
                String weather = (String) msg.obj;
                Log.i(TAG, "handleMessage: 主线程收到了天气数据--weather--"+weather);

                //解析json数据
                try {
                    JSONObject jsonObject = new JSONObject(weather);
                    String tem_max = jsonObject.getString("tem1")+"℃";
                    String tem_min = jsonObject.getString("tem2")+"℃";
                    String tem_img = jsonObject.getString("wea_img");
                    String airTips = jsonObject.getString("air_tips");
                    String win_meter = jsonObject.getString("win_meter").replaceAll("km/h","");
                    V = Double.parseDouble(win_meter)*0.2778; //将km/h转化为m/s
                    String humidity = jsonObject.getString("humidity").replaceAll("%","");
                    RH = Double.parseDouble(humidity); //湿度
                    Log.i(TAG, "handleMessage: 湿度："+RH);
                    Ta = Double.parseDouble(jsonObject.getString("tem")); //当前气温
                    lowTemp.setText(tem_min);
                    highTemp.setText(tem_max);
                    weatherText.setText(airTips);
                    Log.i(TAG, "tem:"+tem_max+"-"+tem_min+"-"+tem_img);

                    //设置天气图标
                    if(tem_img.equals("qing"))
                        weatherImg.setImageResource(R.drawable.qing);
                    else if(tem_img.equals("yin"))
                        weatherImg.setImageResource(R.drawable.yin);
                    else if(tem_img.equals("bingbao"))
                        weatherImg.setImageResource(R.drawable.bingbao);
                    else if(tem_img.equals("xue"))
                        weatherImg.setImageResource(R.drawable.xue);
                    else if(tem_img.equals("yu")){
                        weatherImg.setImageResource(R.drawable.yu);
                        isRain = true;
                    }
                    else if(tem_img.equals("yun"))
                        weatherImg.setImageResource(R.drawable.yun);
                    else if(tem_img.equals("shachen"))
                        weatherImg.setImageResource(R.drawable.shachen);
                    else if(tem_img.equals("wu"))
                        weatherImg.setImageResource(R.drawable.wu);
                    else if(tem_img.equals("lei"))
                        weatherImg.setImageResource(R.drawable.lei);

                    level = MatchRecommend.getWeaLevel(latitude, month, Ta, RH, V, isRain);//获取穿衣等级
                    //在可以调整范围内，对用户穿衣等级进行调整
                    level = level+baseLevel;
                    if(level == 5)
                        level--;
                    if(level == -7)
                        level++;
                    Log.i(TAG, "onActivityCreated: weaLevel="+level);
                    clothesOfMatch = MatchRecommend.getMatch(level); //获取穿搭方案
                    getClothesImgOfMatch(clothesOfMatch); //从数据库中查找图片
                    
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            else if(msg.what == 1){
                Log.i(TAG, "handleMessage: 接收到今日搭配——查完数据库信息");
                //检查arrayList中是否都有内容以供推荐
                boolean dataEnough = true;
                for(ArrayList<String> list:clothesImgOfMatch){
                    if(list.size() == 0){
                        dataEnough = false;
                        break;
                    }
                }
                Log.i(TAG, "handleMessage: dataEnough:"+dataEnough);
                if(dataEnough){
                    //切换显示状态
                    bar.setVisibility(View.GONE);
                    matchFeedback.setVisibility(View.VISIBLE);
                    //设置适配器
                    clothesOfMatchAdapter = new ClothesOfMatchAdapter(getActivity(), R.layout.clothes_of_match, clothesImgOfMatch);
                    todayMatchList.setAdapter(clothesOfMatchAdapter);
                    //点击事件——更换该件衣物
                    todayMatchList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                            Log.i(TAG, "onItemClick: 点击position:"+position);
                            ArrayList<String> list = (ArrayList<String>) todayMatchList.getItemAtPosition(position);
                            if(list.size() == 1){
                                Toast.makeText(getActivity().getApplicationContext(), "该件没有可更换的衣物~", Toast.LENGTH_SHORT).show();
                            }else{
                                clothesOfMatchAdapter.changeClothes(position, view);
                            }
                        }
                    });
                }else{
                    bar.setVisibility(View.GONE);
                    //没有获得数据时显示
                    todayMatchList.setEmptyView(nodata);
                }
            }
        }
    };

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mViewModel = new ViewModelProvider(this).get(IndexViewModel.class);
        // TODO: Use the ViewModel

        init();

        //修改地址——选择+修改SharedPreferences
        //  创建选项选择器
        pvOptions = new OptionsPickerView(getActivity());
        //  获取json数据
        String province_data_json = JsonFileReader.getJson(getActivity(), "province_data.json");
        //  解析json数据
        parseJson(province_data_json);
        //  设置三级联动效果
        pvOptions.setPicker(provinceList, cityList, districtList, true);
        pvOptions.setTitle("选择城市");
        //  设置是否循环滚动
        pvOptions.setCyclic(false, false, false);
        // 设置默认选中的三级项目
        pvOptions.setSelectOptions(0, 0, 0);

        //  监听确定选择按钮
        pvOptions.setOnoptionsSelectListener(new OptionsPickerView.OnOptionsSelectListener() {
            @RequiresApi(api = Build.VERSION_CODES.GINGERBREAD)
            @Override
            public void onOptionsSelect(int options1, int option2, int options3) {
                //返回的分别是三个级别的选中位置
                String city = provinceBeanList.get(options1).getPickerViewText();
                Log.i(TAG, "onOptionsSelect: provinceBeanList-city:"+city);
                String address;
                //  如果是直辖市或者特别行政区只设置市和区/县
                if ("北京市".equals(city) || "上海市".equals(city) || "天津市".equals(city) || "重庆市".equals(city) || "澳门".equals(city) || "香港".equals(city)) {
                    address = provinceBeanList.get(options1).getPickerViewText()
                            + "-" + districtList.get(options1).get(option2).get(options3);
                } else {
                    address = provinceBeanList.get(options1).getPickerViewText()
                            + "-" + cityList.get(options1).get(option2)
                            + "-" + districtList.get(options1).get(option2).get(options3);
                }
                //修改sharedPreference中城市
                SharedPreferences sp = getActivity().getSharedPreferences("user", Activity.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();
                editor.putString("user_city", address);
                editor.apply();
                //对city数据分割，eg：“河北省-邯郸市-丛台区”
                String[] cityTemp = address.split("-");
                Log.i(TAG, "onActivityCreated: cityTemp:"+cityTemp);
                if(cityTemp[cityTemp.length-1].length()==1){
                    //“河北省-邯郸市-邱 县”
                    for(int i = 0; i < cityTemp.length; i++){
                        Log.i(TAG, "onOptionsSelect: 1cityTemp:"+cityTemp[i]);
                    }
                    //分割成河北省、邯郸市、邱、null、县
                    String strtmp = cityTemp[cityTemp.length-3]+cityTemp[cityTemp.length-1];
                    siteText.setText(strtmp);
                    weatherCity = cityTemp[cityTemp.length-4];
                    weatherCity = weatherCity.substring(0, weatherCity.length() - 1);
                }else{
                    for(int i = 0; i < cityTemp.length; i++){
                        Log.i(TAG, "onOptionsSelect: 2cityTemp:"+cityTemp[i]);
                    }
                    siteText.setText(cityTemp[cityTemp.length-1]);
                    weatherCity = cityTemp[cityTemp.length-2];
                    weatherCity = weatherCity.substring(0, weatherCity.length() - 1);
                }
                //更新天气
                Log.i(TAG, "onClick: weatherCity:"+weatherCity);
                getWeatherOfCity(weatherCity);
                getCityLocation(weatherCity);//获取纬度
            }
        });
        //点击地点修改
        sitePart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                pvOptions.show();
            }
        });

        //对推荐衣物进行反馈
        matchFeedback.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.GINGERBREAD)
            @Override
            public void onClick(View view) {
                matchFeedbackFun();
            }
        });

    }

    private void init(){
        //检查sharedPreference,获取用户名、城市
        SharedPreferences sp = getActivity().getSharedPreferences("user", Activity.MODE_PRIVATE);
        PreferenceManager.getDefaultSharedPreferences(getActivity());
        String userName = sp.getString("user_name","");
        String userCity = sp.getString("user_city","");
        userId = sp.getInt("user_id",0);
        jdbcUrl = sp.getString("jdbc_url", "");
        jdbcUser = sp.getString("jdbc_user","");
        jdbcPassword = sp.getString("jdbc_password","");
        baseLevel = sp.getInt("base_level",0);
        Log.i(TAG, "init: baseLevel:"+baseLevel);
        feedbackNum = sp.getInt("feedback_num", 0);

        //对city数据分割，eg：“河北省-邯郸市-丛台区”
        String[] cityTemp = userCity.split("-");
        Log.i(TAG, "onActivityCreated: cityTemp:"+cityTemp);
        welcomeUser.setText(userName);
        if(cityTemp[cityTemp.length-1].length()==1){
            //“河北省-邯郸市-邱 县”
            String strtmp = cityTemp[cityTemp.length-3]+cityTemp[cityTemp.length-1];
            siteText.setText(strtmp);
            weatherCity = cityTemp[cityTemp.length-4];
            weatherCity = weatherCity.substring(0, weatherCity.length() - 1);
        }else{
            siteText.setText(cityTemp[cityTemp.length-1]);
            weatherCity = cityTemp[cityTemp.length-2];
            weatherCity = weatherCity.substring(0, weatherCity.length() - 1);
        }
        //更新天气
        Log.i(TAG, "onClick: weatherCity:"+weatherCity);
        getWeatherOfCity(weatherCity);//获取城市天气情况
        getCityLocation(weatherCity);//获取纬度

        //获取当前日期
        SimpleDateFormat formatter = new SimpleDateFormat("MM-dd");
        Date date = new Date(System.currentTimeMillis());
        Log.i(TAG, "onActivityCreated: Date获取当前日期时间:"+date);
        dateText.setText(formatter.format(date));

        //获取月份
        Calendar cal = Calendar.getInstance();
        month = cal.get(Calendar.MONTH) + 1;
    }

    //  解析json填充集合
    public void parseJson(String str) {
        try {
            //  获取json中的数组
            JSONArray jsonArray = new JSONArray(str);
            //  遍历数据组
            for (int i = 0; i < jsonArray.length(); i++) {
                //  获取省份的对象
                JSONObject provinceObject = jsonArray.optJSONObject(i);
                //  获取省份名称放入集合
                String provinceName = provinceObject.getString("name");
                ArrayList<String> province = new ArrayList<>();//   声明存放省份的集合
                province.add(provinceName);
                provinceList.add(province);
                provinceBeanList.add(new ProvinceBean(provinceName));
                //  获取城市数组
                JSONArray cityArray = provinceObject.optJSONArray("city");
                cities = new ArrayList<>();//   声明存放城市的集合
                districts = new ArrayList<>();//声明存放区县集合的集合
                //  遍历城市数组
                for (int j = 0; j < cityArray.length(); j++) {
                    //  获取城市对象
                    JSONObject cityObject = cityArray.optJSONObject(j);
                    //  将城市放入集合
                    String cityName = cityObject.optString("name");
                    cities.add(cityName);
                    district = new ArrayList<>();// 声明存放区县的集合
                    //  获取区县的数组
                    JSONArray areaArray = cityObject.optJSONArray("area");
                    //  遍历区县数组，获取到区县名称并放入集合
                    for (int k = 0; k < areaArray.length(); k++) {
                        String areaName = areaArray.getString(k);
                        district.add(areaName);
                    }
                    //  将区县的集合放入集合
                    districts.add(district);
                }
                //  将存放区县集合的集合放入集合
                districtList.add(districts);
                //  将存放城市的集合放入集合
                cityList.add(cities);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void getWeatherOfCity(String selectedCity){
        //开启子线程，请求网络
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "run: selectedCity:"+selectedCity);
                //请求网络
                String weatherOfCity = NetUtil.getWeatherOfCity(selectedCity);
                Log.i(TAG, "run: message:"+weatherOfCity);
                //使用Handler将数据传递给主线程
                Message message = Message.obtain();
                message.what = 0;
                message.obj = weatherOfCity;
                mHandler.sendMessage(message);
            }
        }).start();
    }

    //根据城市获取其经纬度
    private void getCityLocation(String cityName){
        Geocoder geocoder = new Geocoder(getContext(), Locale.CHINA);
        try {
            List<Address> addressList = geocoder.getFromLocationName(cityName, 5);
            Address address = addressList.get(0);
            latitude = address.getLatitude();
            double longitude = address.getLongitude();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //根据衣物名称，获取图片进行组合搭配
    private void getClothesImgOfMatch(ArrayList<String[]> clothesOfMatch){
        clothesImgOfMatch.clear();
        //遍历list中每个string[]中每个元素，在数据库中找到适配的衣物
        for(String[] strList : clothesOfMatch){
            ArrayList<String> clothesImg = new ArrayList<>();
            new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.i(TAG, "run: 数据库根据名称查找衣物");
                        try {
                            Class.forName("com.mysql.jdbc.Driver");
                            Connection cn = DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
                            Statement st = (Statement)cn.createStatement();

                            for(String str : strList) {
                                Log.i(TAG, "getClothesImgOfMatch: clothes名称：" + str);
                                String sql = "select * from clothes where c_uid=" + userId + " and c_name='" + str + "'";
                                ResultSet rs = st.executeQuery(sql);
                                System.out.println("连接数据库成功");
                                //查询出数据，将其放在String[]中
                                while (rs.next()) {
                                    clothesImg.add(rs.getString("c_img"));
                                }
                                rs.close();
                            }
                            
                            st.close();
                            cn.close();
                        } catch (ClassNotFoundException | SQLException e) {
                            Log.i(TAG, "run:SQL fail!!!__"+e);
                            e.printStackTrace();
                        }
                        //使用Handler将数据传递给主线程__我已经查找完所有衣物了
                        Message message = Message.obtain();
                        message.what = 1;
                        message.obj = 1;
                        mHandler.sendMessage(message);
                        clothesImgOfMatch.add(clothesImg);
                    }
                }).start();
        }

    }

    //对推荐衣物进行反馈，调整穿衣等级
    @RequiresApi(api = Build.VERSION_CODES.GINGERBREAD)
    private void matchFeedbackFun(){
        //出现弹窗进行反馈
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("反馈")
                .setMessage("请选择推荐穿搭情况？")
                .setPositiveButton("热", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Log.i(TAG, "onClick: 反馈对话框事件处理——hot");
                        feedbackNum++;
                        if(feedbackNum == 2){
                            //对level进行调整
                            baseLevel++;
                            Log.i(TAG, "onClick: hot-baseLevel:"+baseLevel);
                            feedbackNum = 0;
                        }
                        //对SharedPreferences中调整
                        SharedPreferences sp = getActivity().getSharedPreferences("user", Activity.MODE_PRIVATE);
                        SharedPreferences.Editor editor = sp.edit();
                        Log.i(TAG, "matchFeedbackFun: edit-baseLevel:"+baseLevel);
                        editor.putInt("base_level", baseLevel); //根据用户自身情况，进行穿衣等级的调整
                        editor.putInt("feedback_num", feedbackNum); //反馈次数hot
                        editor.apply();
                    }
                })
                .setNegativeButton("冷", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Log.i(TAG, "onClick: 反馈对话框事件处理——cold");
                        feedbackNum--;
                        if(feedbackNum == -2){
                            //对level进行调整
                            baseLevel--;
                            Log.i(TAG, "onClick: cold-baseLevel:"+baseLevel);
                            feedbackNum = 0;
                        }
                        //对SharedPreferences中调整
                        SharedPreferences sp = getActivity().getSharedPreferences("user", Activity.MODE_PRIVATE);
                        SharedPreferences.Editor editor = sp.edit();
                        Log.i(TAG, "matchFeedbackFun: edit-baseLevel:"+baseLevel);
                        editor.putInt("base_level", baseLevel); //根据用户自身情况，进行穿衣等级的调整
                        editor.putInt("feedback_num", feedbackNum); //反馈次数cold
                        editor.apply();
                    }
        });
        builder.create().show();


    }

}